package com.greyshark.lib.bluetooth.extensions

import java.math.BigInteger
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.util.Locale

fun ByteArray.toHexString(): String {
  if (this.isEmpty()) {
    return ""
  }
  val sb = StringBuilder(this.size)
  for (byteChar in this) {
    sb.append(String.format(Locale.ENGLISH, "%02X ", byteChar))
  }
  return sb.toString()
}

fun ByteArray.toHex(isLittleEndian: Boolean = true): Long {
  var result = 0L
  if (isLittleEndian) {
    for (i in this.indices) {
      result = result or ((this[i].toLong() and 0xFF) shl (i * 8))
    }
    return result
  } else {
    for (i in this.indices) {
      result = result or ((this[i].toLong() and 0xFF) shl ((this.size - 1 - i) * 8))
    }
    return result
  }
}
 fun Number.toLittleEndianByteArray(): ByteArray {
  return when (val num = this) {
    is Short -> ByteBuffer.allocate(2)
      .order(ByteOrder.LITTLE_ENDIAN)
      .putShort(num)
      .array()

    is Int -> ByteBuffer.allocate(4)
      .order(ByteOrder.LITTLE_ENDIAN)
      .putInt(num)
      .array()

    is Long -> ByteBuffer.allocate(8)
      .order(ByteOrder.LITTLE_ENDIAN)
      .putLong(num)
      .array()

    else -> throw IllegalArgumentException("不支持的大小端转换类型: $this")
  }
}

fun Long.toByteArrayReverse(): ByteArray {
  require(this >= 0) {
    "只支持非负数"
  }
  val bigEndian = BigInteger.valueOf(this).toByteArray()
  // BigInteger.toByteArray() 可能多带一个符号位的 0x00，要去掉
  val unsigned = if (bigEndian[0].toInt() == 0) {
    bigEndian.drop(1).toByteArray()
  } else {
    bigEndian
  }
  return unsigned.reversedArray()
}

fun Long.toFixByteArrayReverse(fixedLength: Int = 8): ByteArray {
  require(this >= 0) { "只支持非负数" }
  require(fixedLength > 0 && fixedLength <= 8) { "长度必须在1到8之间" }
  val bigEndian = BigInteger.valueOf(this).toByteArray()
  // BigInteger.toByteArray() 可能多带一个符号位的 0x00，要去掉
  val unsigned = if (bigEndian[0].toInt() == 0) {
    bigEndian.drop(1).toByteArray()
  } else {
    bigEndian
  }
  val reversed = unsigned.reversedArray()
  // 保证返回指定长度，在低位（开头）填充0
  val padded = if (reversed.size < fixedLength) {
    ByteArray(fixedLength - reversed.size) { 0.toByte() } + reversed
  } else {
    // 如果超过长度，取低fixedLength字节（因为是小端序，低字节在前）
    reversed.takeLast(fixedLength).toByteArray()
  }
  return padded
}

/**
 * 将 Long 转换为小端字节数组
 * @param size 需要的字节数 (2,4,6,8)
 */
fun Long.toLittleEndian(size: Int): ByteArray {
  require(size in listOf(2, 4, 6, 8)) {
    "size 必须是 2, 4, 6, 8"
  }
  val result = ByteArray(size)
  for (i in 0 until size) {
    result[i] = (this shr (8 * i)).toByte()
  }
  return result
}